/*************************************************************************************
 *
 *  Revolution Engine
 *  Copyright (C) 2009 Felipe Apablaza
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ************************************************************************************/

#include <list>
#include <algorithm>
#include <RevEng/IObject.hpp>
#include "ObjRecycler.hpp"
#include "ObjFactory.hpp"

namespace RevEng
{
	std::list<Enum> g_lstClassId;

	//Decrease the reference counter
	void IObject::Release()
	{
		--m_nRefCount;

		if (m_nRefCount == 0)
		{
			if (std::find(	g_lstClassId.begin(), 
							g_lstClassId.end(), 
							this->GetClassId()) != g_lstClassId.end())
			{
				if (ObjRecycler::Instance()->IsRegistered( typeid(*this) ) == false)
					ObjRecycler::Instance()->Register( typeid(*this) );

				ObjRecycler::Instance()->Put( this );
			}
			else
				delete this;
		}
	}


	//Instance a new object.
	IObject* IObject::New( Enum ClassId )
	{
		IObject* Obj;

		const std::type_info& TypeInfo = ObjFactory::Instance()->GetTypeInfo(ClassId);

		Obj = ObjRecycler::Instance()->Get(TypeInfo);

		if (Obj == NULL)
			Obj = ObjFactory::Instance()->New(ClassId);

		return Obj;
	}


	//
	void IObject::RegisterObjCreator( IObjCreator* Creator )
	{
		ObjFactory::Instance()->RegObjCreator(Creator);
	}

	void IObject::Recycle( Enum ClassId )
	{
		g_lstClassId.push_back(ClassId);
	}
}
